package org.paterczm.watermarker;

import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import javax.imageio.ImageIO;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

public class Watermarker {

	private Image watermarkImage = null;

	private Dimension modelDimentions;

	private int jpgQuality = 75;

	public Watermarker(String watermarkFilePath, Dimension modelDimentions) throws IOException, InterruptedException {
		this.modelDimentions = modelDimentions;

		watermarkImage = loadImage(new File(watermarkFilePath));
	}

	private Image loadImage(File f) throws IOException, InterruptedException {
		MediaTracker mediaTracker = new MediaTracker(new Container());

		Image image = Toolkit.getDefaultToolkit().getImage(f.getAbsolutePath());

		mediaTracker.addImage(image, 0);

		mediaTracker.waitForID(0);

		return image;

	}

	public static void saveJPGBufferedImage(BufferedImage image, String outputFilePath, int quality) throws IOException {
		BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(outputFilePath));
		JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
		JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(image);

		param.setQuality((float) quality / 100.0f, false);
		encoder.setJPEGEncodeParam(param);
		encoder.encode(image);
		out.close();
	}

	public void stampWatermark(BufferedImage image) {
		Graphics2D graphics2D = image.createGraphics();

		float nx = image.getWidth(null) * 1f / modelDimentions.width;
		float ny = image.getHeight(null) * 1f / modelDimentions.height;

		int x2 = (int) (watermarkImage.getWidth(null) * nx);
		int y2 = (int) (watermarkImage.getHeight(null) * nx); // ny?
		int x1 = (int) ((image.getWidth(null) - x2));
		int y1 = (int) ((image.getHeight(null) - y2));

		graphics2D.drawImage(watermarkImage, x1, y1, x2, y2, null);

		graphics2D.dispose();
	}

	public static void watermark(Profile profile, String inputDirectory, String outputDirectory) throws IOException, InterruptedException {

		Watermarker watermarker = null;
		try {
			watermarker = new Watermarker(profile.getWatermarkFileName(), profile.getModelDimensions());
		} catch (Exception e1) {
			System.out.println(e1.toString());
		}

		if ((new File(inputDirectory)).isFile()) {
			// watermarker.stampWatermark(o.getInputDirectory(), o
			// .getOutputDirectory(), new ImageResizer(o.getMaximumImageSize(), o.isResizeToFit()));
		} else {

			FileManager m = new FileManager();
			m.captureFiles(new File(inputDirectory));

			for (String remMatch : profile.getRemoveMatches())
				m.removeMatches(remMatch);

			for (String keepMatch : profile.getKeepeMatches())
				m.keepMatches(keepMatch);

			for (File f : m.getFiles()) {
				try {
					System.out.print(f.getAbsolutePath() + "... ");
					String relativePath = f.getAbsolutePath().substring(inputDirectory.length(), f.getAbsolutePath().length());

					// load
					BufferedImage bufferedImage = ImageIO.read(f);
					if (bufferedImage == null) {
						System.out.println("Error! Skipping this file.");
						continue;
					}

					// scale if necessary
					float ratio = ImageResizer.getRatio(bufferedImage, profile.getMaximumImageSize());
					if (ratio < 1) {
						bufferedImage = ImageResizer.resizeImage(bufferedImage, ratio);
						System.out.print("rescaled... ");
					}

					// watermark
					if (watermarker != null)
						watermarker.stampWatermark(bufferedImage);

					// save
					String outputFilePath = outputDirectory + relativePath;
					(new File((new File(outputFilePath)).getParent())).mkdirs();
					saveJPGBufferedImage(bufferedImage, outputFilePath, profile.getJpgQuality());

					/*
					 * watermarker.stampWatermark(f.getAbsolutePath(), o .getOutputDirectory() + relativePath, new ImageResizer(o.getMaximumImageSize(), o.isResizeToFit()));
					 */
					System.out.println("OK");
				} catch (IllegalArgumentException e) {
					System.out.println(e.toString());
				}

			}

			System.out.println("END");
		}

	}

	/**
	 * @param args
	 */

	public static void main(String[] args) {

		/*
		 * try {
		 *
		 * FileManager m = new FileManager(); m.captureFiles(new File("/home/marek/albums")); // m.removeMatches("^normal_(.*)"); m.removeMatches("^thumb_(.*)");
		 * m.keepMatches("^(.*)\\.jpg");
		 *
		 * Watermarker watermarker = new Watermarker("watermark.png", new Dimension(1024, 768)); for (File f : m.getFiles()) watermarker.stampWatermark(f.getAbsolutePath(), f
		 * .getAbsolutePath());
		 *
		 * } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InterruptedException e) { // TODO Auto-generated catch block
		 * e.printStackTrace(); }
		 */

	}

	public int getJpgQuality() {
		return jpgQuality;
	}

	public void setJpgQuality(int jpgQuality) {
		this.jpgQuality = jpgQuality;
	}

}
